package model.algorithms;

import java.util.ArrayList;
import java.util.List;

import model.config.Config;
import model.framework.*;

public class FirstFit extends Algorithm {
	
	public void run(List<Block> blocks, Field field) {
		
		
		 for ( Block block : blocks ){
			
			 // get the surface of 
			 int[] fieldSurface = field.getSurface();
			 
			 /* build the bins for all rotations*/
			 List<List<Frame>> binList = new ArrayList<List<Frame>>();
			 binList.add(this.buildFrames(block.getBlockType(), fieldSurface,0));
			 if (block.getRotations() > 1 && block.getBlockType().getWidth(0) != block.getBlockType().getWidth(1)){
				 binList.add(this.buildFrames(block.getBlockType(), fieldSurface,1));
			 }
			 
			 // loop through bins, place the block
			 boolean blockIsPlaced = false;
			
			 while(!blockIsPlaced) {
			 				 
				Frame chosenBin = null;
				
				boolean binIsChosen = false;
				int rotation = -1;
				for (int rot = 0; rot < block.getRotations() && !binIsChosen; rot++){
					int binListIndex = -1;
					if (binList.size() == 1){
						binListIndex = 0;
					} else {
						binListIndex = rot % 2;
					}
					for( Frame frame : binList.get(binListIndex) ){
						if (frame.heightAfterPlacing(block, rot) != -1) {
							chosenBin = frame;
							binIsChosen = true;
							rotation = rot;
							break;
						}
					}
				}
		
				if(binIsChosen) {
					int x = chosenBin.getFieldx();
					//int y = this.calculateLowestSurface(chosenBin.getDimensions());
					int y = chosenBin.heightAfterPlacing(block, rotation) - block.getBlockType().getHeight(rotation);
					
					block.setX(x);
					block.setY(y);
					block.setRotation(rotation);
					
					field.placeBlock( block );
					blockIsPlaced = true;
					field.printField();
				} else {
					// block doesnt fit in bins, add row to bins
					for (List<Frame> frames : binList){
						for( Frame frame : frames){
							frame.addRow();
						}	
					}
				}
			}
		}
	}
	
	@Override
	public String toString() {
		return "FirstFit";
	}
}

